package main

import (
	"context"
	"flag"
	"fmt"
	"github.com/go-kit/kit/log"
	kitprometheus "github.com/go-kit/kit/metrics/prometheus"
	stdprometheus "github.com/prometheus/client_golang/prometheus"
	"golang.org/x/time/rate"
	endpoint2 "http_rest/register/endpoint"
	"http_rest/register/middleware"
	"http_rest/register/register"
	"http_rest/register/service"
	"http_rest/register/transport"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"
)
//ifconfig|grep inet
//$ ./reg -consul.host 127.0.0.1 -consul.port 8500 -service.host 10.222.97.16 -service.port 9000
func  main()  {
	var(
		consulHost = flag.String("consul.host", "", "consul ip address")
		consulPort = flag.String("consul.port", "", "consul port")
		serviceHost = flag.String("service.host", "", "service ip address")
		servicePort = flag.String("service.port", "", "service port")
	)
	flag.Parse()

	ctx := context.Background()
	errChan := make(chan error)

	var logger log.Logger;{
		logger = log.NewLogfmtLogger(os.Stderr)
		logger = log.With(logger, "ts", log.DefaultTimestampUTC)
		logger = log.With(logger, "caller", log.DefaultCaller)
	}

	fieldKeys := []string{"method"}
	requestCount := kitprometheus.NewCounterFrom(stdprometheus.CounterOpts{
		Namespace: "raysonxin",
		Subsystem: "arithmetic_service",
		Name:      "request_count",
		Help:      "Number of requests received.",
	}, fieldKeys)
	requestLatency := kitprometheus.NewSummaryFrom(stdprometheus.SummaryOpts{
		Namespace: "raysonxin",
		Subsystem: "arithemetic_service",
		Name:      "request_latency",
		Help:      "Total duration of requests in microseconds.",
	}, fieldKeys)

	//1.
	var svc service.Service
	svc = service.ArithmeticService{}
	//2.
	//var svc = service.ArithmeticService{}

	//add middleware
	svc = middleware.LoggingMiddleware(logger)(svc)
	svc = middleware.Metrics(requestCount, requestLatency)(svc)
	endpoint := endpoint2.MakeArithmeticEndpoint(svc)
	rateBucket := rate.NewLimiter(rate.Every(time.Second*1), 100)
	endpoint = middleware.NewTokenBucketLimiterWithBuildIn(rateBucket)(endpoint)
	healthEndpoint := endpoint2.MakeHealthCheckEndpoint(svc)
	endpts := endpoint2.ArithmeticEndpoints{
		ArithmeticEndpoint: endpoint,
		HealthCheckEndpoint: healthEndpoint,
	}

	r := transport.MakeHttpHandler(ctx, endpts, logger)
	register := register.Register(*consulHost, *consulPort, *serviceHost, *servicePort, logger)

	go func() {
		fmt.Println("Http Server start at port:"+*servicePort)
		register.Register()
		handler := r
		errChan<- http.ListenAndServe(":"+*servicePort, handler)
	}()

	go func() {
		c := make(chan os.Signal,1)
		signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
		errChan <- fmt.Errorf("%s", <-c)
	}()

	error := <-errChan
	register.Deregister()
	fmt.Println(error)
}
